21. Scope/$scope in Controllers

Scope/$scope in Controllers

Scope has changed a little bit as the Angular project has matured. You don't interact directly with the scope object as much as you used to. I want to point this out because some articles and tutorials can make it a bit confusing to see a $scope object used in some examples, but not in others.

For example, this is the controller we've been using (the recommended way!):

angular.module('udaciMealsApp')
    .controller('MenuCtrl', function () {
        this.id = 'chipotle-shrimp-wrap';
        this.name = 'Chipotle Shrimp Wrap';
        this.img = 'chipotle-shrimp-wrap.jpg';
        this.rating = 4.2;
    });

The following is an older way to write this same controller (the old way!):

angular.module('udaciMealsApp')
    .controller('MenuCtrl', function ($scope) {
        $scope.id = 'chipotle-shrimp-wrap';
        $scope.name = 'Chipotle Shrimp Wrap';
        $scope.img = 'chipotle-shrimp-wrap.jpg';
        $scope.rating = 4.2;
    });

Doing it this way, though, where a $scope object is passed to the controller and used in the body, changes the way a template needs to be written. Using $scope directly in a controller causes it to directly modify the Scope object. Directly modifying the Scope object makes the template end up like this:

<div class="container">
    <div class="row" ng-controller="MenuCtrl">
        <div class="items-container">
            <h4>{{name}}</h4>
            <p>{{rating}}</p>
            <p>{{img}}</p>
        </div>
    </div>
</div>

Notice that the ng-controller attribute is just MenuCtrl instead of MenuCtrl as menu. An instance of the Menu Controller is created with ng-controller="MenuCtrl as menu" (which is why the template has {{menu.color}}) while ng-controller="MenuCtrl" just calls the function and directly modifies the scope object (which is why the template will need {{color}}).

We shouldn't fiddle with the scope object, but let Angular handle it as much as possible. So when you make your controllers and templates, make sure you do not use $scope in your controller but make sure to use this and the controller as syntax.